home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / encodings / utf_8_sig.py < prev    next >
Encoding:
Python Source  |  2006-06-20  |  3.2 KB  |  101 lines

  1. """ Python 'utf-8-sig' Codec
  2. This work similar to UTF-8 with the following changes:
  3.  
  4. * On encoding/writing a UTF-8 encoded BOM will be prepended/written as the
  5.   first three bytes.
  6.  
  7. * On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these
  8.   bytes will be skipped.
  9. """
  10. import codecs
  11.  
  12. ### Codec APIs
  13.  
  14. def encode(input, errors='strict'):
  15.     return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input))
  16.  
  17. def decode(input, errors='strict'):
  18.     prefix = 0
  19.     if input.startswith(codecs.BOM_UTF8):
  20.         input = input[3:]
  21.         prefix = 3
  22.     (output, consumed) = codecs.utf_8_decode(input, errors, True)
  23.     return (output, consumed+prefix)
  24.  
  25. class IncrementalEncoder(codecs.IncrementalEncoder):
  26.     def __init__(self, errors='strict'):
  27.         codecs.IncrementalEncoder.__init__(self, errors)
  28.         self.first = True
  29.  
  30.     def encode(self, input, final=False):
  31.         if self.first:
  32.             self.first = False
  33.             return codecs.BOM_UTF8 + codecs.utf_8_encode(input, self.errors)[0]
  34.         else:
  35.             return codecs.utf_8_encode(input, self.errors)[0]
  36.  
  37.     def reset(self):
  38.         codecs.IncrementalEncoder.reset(self)
  39.         self.first = True
  40.  
  41. class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
  42.     def __init__(self, errors='strict'):
  43.         codecs.BufferedIncrementalDecoder.__init__(self, errors)
  44.         self.first = True
  45.  
  46.     def _buffer_decode(self, input, errors, final):
  47.         if self.first and codecs.BOM_UTF8.startswith(input): # might be a BOM
  48.             if len(input) < 3:
  49.                 # not enough data to decide if this really is a BOM
  50.                 # => try again on the next call
  51.                 return (u"", 0)
  52.             (output, consumed) = codecs.utf_8_decode(input[3:], errors, final)
  53.             self.first = False
  54.             return (output, consumed+3)
  55.         return codecs.utf_8_decode(input, errors, final)
  56.  
  57.     def reset(self):
  58.         codecs.BufferedIncrementalDecoder.reset(self)
  59.         self.first = True
  60.  
  61. class StreamWriter(codecs.StreamWriter):
  62.     def reset(self):
  63.         codecs.StreamWriter.reset(self)
  64.         try:
  65.             del self.encode
  66.         except AttributeError:
  67.             pass
  68.  
  69.     def encode(self, input, errors='strict'):
  70.         self.encode = codecs.utf_8_encode
  71.         return encode(input, errors)
  72.  
  73. class StreamReader(codecs.StreamReader):
  74.     def reset(self):
  75.         codecs.StreamReader.reset(self)
  76.         try:
  77.             del self.decode
  78.         except AttributeError:
  79.             pass
  80.  
  81.     def decode(self, input, errors='strict'):
  82.         if len(input) < 3 and codecs.BOM_UTF8.startswith(input):
  83.             # not enough data to decide if this is a BOM
  84.             # => try again on the next call
  85.             return (u"", 0)
  86.         self.decode = codecs.utf_8_decode
  87.         return decode(input, errors)
  88.  
  89. ### encodings module API
  90.  
  91. def getregentry():
  92.     return codecs.CodecInfo(
  93.         name='utf-8-sig',
  94.         encode=encode,
  95.         decode=decode,
  96.         incrementalencoder=IncrementalEncoder,
  97.         incrementaldecoder=IncrementalDecoder,
  98.         streamreader=StreamReader,
  99.         streamwriter=StreamWriter,
  100.     )
  101.